Conversation
brandonkachen
left a comment
There was a problem hiding this comment.
looks good for a first pass. but lots of LLM-slop here, particularly code patterns like this:
const customerId =
typeof stripeSubscription.customer === 'string'
? stripeSubscription.customer
: stripeSubscription.customer.id
we can instead add a generic function to do this:
export function resolveExpandableId<T extends { id: string }>(
value: string | T,
): string {
return typeof value === 'string' ? value : value.id
}
const customerId = resolveExpandableId(stripeSubscription.customer)
|
oh and please make sure to run the db migration locally once you're happy with the db schema, so we have all the artifact files that drizzle will apply on prod when you merge |
brandonkachen
left a comment
There was a problem hiding this comment.
looks good! most of my comments are code readability nits/suggestions, so that means we're on the right track!
| case 'customer.subscription.updated': | ||
| case 'customer.subscription.updated': { | ||
| const sub = event.data.object as Stripe.Subscription | ||
| if (sub.metadata?.organization_id) { |
There was a problem hiding this comment.
aren't we deprecating the orgs stuff? if so, we can just error out earlier on in the webhook, instead of running code we don't want to maintain and cluttering up each of these cases
| subscription.stripe_subscription_id, | ||
| { | ||
| items: [{ id: itemId, price: newPriceId }], | ||
| proration_behavior: 'create_prorations', |
There was a problem hiding this comment.
IMPORTANT: this is incorrect. We want upgrades prorate now, downgrades scheduled at period end. ChatGPT says:
Upgrades
Use:
- proration_behavior: "always_invoice"
- (recommended) payment_behavior: "pending_if_incomplete" to avoid granting the upgrade if payment fails
Downgrades
Don’t “change price now”. Instead, schedule the downgrade for current_period_end using a Subscription Schedule. Stripe explicitly suggests subscription schedules if you’re changing a subscription at the end of the billing period.
Conceptually:
- Phase 1: current price until current_period_end
- Phase 2: cheaper price starting at current_period_end
Set the phase transition proration_behavior: "none" so there’s no proration credit at the transition
This gives you exactly: “stay on current tier until renewal, then downgrade, no credit”.
There was a problem hiding this comment.
| }, | ||
| ) | ||
|
|
||
| try { |
There was a problem hiding this comment.
maybe this try/catch block can go into a webhook; this function/route can just focus on being a wrapper around stripe, and then the webhook can deal with the consequences.
this would let us organize our logic using:
- routes as proxies for stripe actions
- webhooks to propagate changes from stripe to our system
jahooma
left a comment
There was a problem hiding this comment.
first pass, will address remaining
No description provided.